home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Megahits 5
/
Megahits 5 (1994)(GTI - Rhein-Main-Soft)(DE)(Disc 2 of 2)[!].iso
/
archive
/
show
/
jpegagasrc10.lha
/
jpegaga
/
EncodeHAM8.asm
< prev
next >
Wrap
Assembly Source File
|
1994-05-28
|
11KB
|
254 lines
; jpegAGA utility function written by Günther Röhrich
; this code is Public Domain and may be used with other programs
; this version is for 68020+ processors only
; it is is called from C:
; EncodeHAM8(char *rorig, char *gorig, char *borig, char *yham, int xsize);
; rorig = original row (red, 8 bit)
; gorig = original row (green, 8 bit)
; borig = original row (blue, 8 bit)
; yham = row in HAM8 chunky format
; xsize = size of row in pixels
MACHINE MC68020
;NOTE: GCC stores all data as 32 bit at subroutine calls!
rorig EQU 44
gorig EQU 48
borig EQU 52
yham EQU 56 ;pointer to actual row (HAM)
xsize EQU 60 ;number of pixels (x)
XREF _Mult_Table ;address of multiplication table
XDEF _EncodeHAM8 ;entry point for function
XREF _ColorCache ;an 256K array
XREF _ColorTable ;an array with 64 colors
* XDEF _blue_left ;only for debugging purposes
* XDEF _search_finish ;only for debugging
* XDEF _MaxError
* XDEF _MaxErrorPos
* XDEF _hit ;only for debugging
* XDEF _t1 ;only for debugging
dseg
cnop 0,4
_blue_left: dc.b 0 ;this order is better for HAM-encoding
_red_left: dc.b 0
_green_left: dc.b 0,0 ;additional dummy-value for faster longword access
cnop 0,2
_offset_orig: dc.w 0
_offset_ham: dc.w 0
_CacheOffset dc.l 0
xcounter dc.w 0
cseg
;register usage: D0 = general purpose register
; D1 = contains afterwards the error
; D2 = orig_blue
; D3 = orig_red
; D4 = orig_green
; D5 = color that should be set
; D6 = offset to actual pixel (HAM)
; D7 = offset for color table / (0,1,2) at HAM
; A0 = best color so far (color+1)*3
; A1 = pointer to multiplication table
; A2 = pointer to color table / to _blue_left
; A3 = smallest error that has been reached so far
; A4 = used by the Aztec assembler (small data model)
; A5 = not used
; A6 = pointer to the actual row (HAM)
;computing the difference of color values is done with signed 8 bit
;arithmetic
;the maximum error value is 63^2+63^2+63^2=11907
;the summation has to be done therefore with 16 bits
;Initializing
_EncodeHAM8: movem.l D2-D7/A2-A3/A5/A6,-(A7) ;store registers
lea _blue_left,A0 ;load start of left colors
lea _ColorTable,A2
move.l (A2),(A0) ;initialize left colors
moveq.l #0,D6 ;initialize ham offset
move.l yham(sp),A6
lea _Mult_Table,A1
lea 255*2(A1),A1
search_begin: move.w xcounter,D7
move.b ([rorig,sp],D7.W),D3 ;load original red
lsr.b #2,D3
move.b ([gorig,sp],D7.W),D4 ;load original green
lsr.b #2,D4
move.b ([borig,sp],D7.W),D2 ;load original blue
lsr.b #2,D2
addq.w #1,D7
move.w D7,xcounter
move.w #15000,A3 ;dummy-value for minimum error so far
lea _ColorTable,A2
moveq.l #0,D7 ;initialize offset for color table
;First take a look if we have the value already in the cache
moveq.l #0,D0
moveq.l #0,D1
move.b D3,D0 ;compute the cache offset
lsl.l #6,D0
or.b D4,D0
lsl.l #6,D0
or.b D2,D0 ;now we have the offset in D0
movea.l _ColorCache,A0 ;load start address of the cache
move.b 0(A0,D0.l),D1 ;take the value from the cache
bne _hit ;jump if we have a cache hit
move.l D0,_CacheOffset ;store the offset to avoid recomputing it
move.l #3,A0 ;dummy-value for best colornumber so far
; (3 means color 0)
search_start: bsr _compute_error
cmp.w D1,A3 ;A3 <= D1 ?
bls.s search4
move.w D1,A3 ;D1 is smaller than A3, store it
move.w D7,A0 ;store color number
tst.w D1 ;do we have the correct color ?
beq search5 ;then finish immediately
search4: cmp.w #64*3,D7 ;have we reached highest colornum ?
bne.s search_start ;no, then once again
;A0 contains now (colornumber+1)*3
;A3 contains the error for that colornumber
_t1: move.w A0,D0
movea.l _ColorCache,A2
move.l _CacheOffset,D1
move.b D0,0(A2,D1.l) ;store the value in the cache
lea _blue_left,A2 ;restore A2
;compute the error when using modify mode
start_ham6: move.b D2,D0 ;load orig_blue
moveq.l #0,D7 ;assume blue should be changed
move.b D2,D5 ;store value to change
sub.b _blue_left,D0 ;D0=D0-_blue_left
bpl.s ham6_1
neg.b D0 ;make result positive
ham6_1: move.b D0,D1 ;store maximum error so far
move.b D3,D0 ;load orig_red
sub.b _red_left,D0 ;D0=D0-_red_left
bpl.s ham6_2
neg.b D0
ham6_2: cmp.b D0,D1 ;check D1-D0
bge.s ham6_3 ;jump if D1>=D0
move.b D0,D1 ;store new maximum error
moveq.l #1,D7 ;assume red should be changed
move.b D3,D5 ;store value to change
ham6_3: move.b D4,D0 ;load orig_green
sub.b _green_left,D0 ;D0=D0-_green_left
bpl.s ham6_4
neg.b D0
ham6_4: cmp.b D0,D1
bge.s ham6_5
move.b D0,D1 ;store maximum error
moveq.l #2,D7 ;green should be changed
move.b D4,D5 ;store value to change
ham6_5: lea _blue_left,A2
move.b D5,0(A2,D7.W) ;perform change
ham_error: moveq.l #0,D1
moveq.l #0,D0
move.b D2,D0 ;load blue_origin
sub.b (A2)+,D0 ;D0 = blue_color - blue_origin
ext.w D0
add.w 0(A1,D0.W*2),D1
move.b D3,D0 ;load red_origin
sub.b (A2)+,D0 ;D0 = red_color - red_origin
ext.w D0
add.w 0(A1,D0.W*2),D1
move.b D4,D0 ;load green_origin
sub.b (A2)+,D0 ;D0 = green_color - green_origin
ext.w D0
add.w 0(A1,D0.W*2),D1
cmpa.w D1,A3 ;check what error is smaller
bls.s _search_finish ;jump if colortable is better
ham6_9: add.b #1,D7 ;needed to get correct code
lsl.b #6,D7 ;HAM8-adjust
or.b D5,D7
move.b D7,(A6,D6.W) ;store code in bitmap
addq.w #1,D6 ;increase _offset_ham
cmp.l xsize(sp),D6 ;end of column ?
bne search_begin
bra.s search_end
_search_finish: move.w A0,D0
lea _ColorTable,A2
lea -3(A2,D0.W),A3 ;load A3 with pointer to colors
divu #3,D0
subq.w #1,D0
move.b D0,0(A6,D6.W) ;store colornumber in bitmap
lea _blue_left,A2
move.l (A3),(A2)
addq.w #1,D6 ;increase _offset_ham
cmp.l xsize(sp),D6 ;have we reached the end ?
bne search_begin
search_end: movem.l (A7)+,D2-D7/A2-A3/A5/A6 ;restore registers
clr.w xcounter
rts ;jump back to caller
;we jump here if we have reached error 0 by colortable only
;and there was not a cache hit
search5: move.w A0,D0
movea.l _ColorCache,A2
move.l _CacheOffset,D1
move.b D0,0(A2,D1.l) ;store the value in the cache
bra.s _search_finish
;we jump here if we have a cache hit
;D1 contains the best color number, but we have to compute the error
_hit: subq.w #3,D1 ;correct color number
move.w D1,D7
bsr.s _compute_error
move.w D1,A3 ;D1 is smaller than A3, store it
move.w D7,A0 ;store color number
bra start_ham6 ;continue with HAM encoding
;compute the error
_compute_error: moveq.l #0,D1
moveq.l #0,D0
move.b D2,D0 ;load blue_origin
sub.b 0(A2,D7.W),D0 ;D0 = blue_color - blue_origin
ext.w D0 ;extend result to word
add.w 0(A1,D0.W*2),D1
addq.w #1,D7 ;advance color table offset
move.b D3,D0 ;load red_origin
sub.b 0(A2,D7.W),D0 ;D0 = red_color - red_origin
ext.w D0
add.w 0(A1,D0.W*2),D1
addq.w #1,D7 ;advance color table offset
move.b D4,D0 ;load green_origin
sub.b 0(A2,D7.W),D0 ;D0 = green_color - green_origin
ext.w D0
add.w 0(A1,D0.W*2),D1 ;D1 = D1 + D0*D0
addq.w #1,D7 ;advance color table offset
rts